package com.gateway.service.filter.pre;

import com.gateway.api.domain.vo.ApiInfo;
import com.gateway.api.util.BeanUtil;
import com.gateway.api.util.IPUtil;
import com.gateway.service.ApiService;
import com.gateway.service.annotation.GatewayFilterAttr;
import com.gateway.service.filter.GatewayFilter;
import com.gateway.service.runner.RequestContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.RequestEntity;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StreamUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collections;
import java.util.List;

/**
 * @Description: 构建Request的信息放在requestEntity里面
 * @author: shaoyu1
 * @date: 2019/11/4 15:50
 */
@GatewayFilterAttr(order = 99)
@Slf4j
public class GenerateRequestFilter extends GatewayFilter {
    @Override
    public void run() {
        RequestContext ctx =RequestContext.getCurrentContext();
        HttpServletRequest servletRequest = ctx.getRequest();
        String targetURL = getTargetURL(servletRequest.getRequestURI());
        RequestEntity<byte[]> requestEntity = null;
        try {
            requestEntity = createRequestEntity(servletRequest, targetURL);
        } catch (Exception e) {
            e.printStackTrace();
        }
        ctx.setRequestEntity(requestEntity);
    }

    private String getTargetURL(String requestURI) {
        ApiService apiservice = BeanUtil.getBean(ApiService.class);
        ApiInfo apiInfo = apiservice.getTargetURLFromCache(requestURI);
        String targetURL = "http://"+apiInfo.getOrgHost()+apiInfo.getOrgUrl();
        return targetURL;
    }

    private RequestEntity<byte[]> createRequestEntity(HttpServletRequest request, String url) throws URISyntaxException, IOException{
        String method = request.getMethod();
        HttpMethod httpMethod = HttpMethod.resolve(method);
        //1、封装请求头
        MultiValueMap<String, String> headers =createRequestHeaders(request);
        //2、封装请求体
        byte[] body = createRequestBody(request);
        System.out.println(new String(body));
        //3、构造出RestTemplate能识别的RequestEntity
        RequestEntity requestEntity = new RequestEntity<byte[]>(body,headers,httpMethod, new URI(url));
        return requestEntity;
    }

    private byte[] createRequestBody(HttpServletRequest request) throws IOException {
        InputStream inputStream = request.getInputStream();
        return StreamUtils.copyToByteArray(inputStream);
    }

    private MultiValueMap<String, String> createRequestHeaders(HttpServletRequest request) {
        HttpHeaders headers = new HttpHeaders();
        List<String> headerNames = Collections.list(request.getHeaderNames());
        for(String headerName:headerNames) {
            List<String> headerValues = Collections.list(request.getHeaders(headerName));
            for(String headerValue:headerValues) {
                headers.add(headerName, headerValue);
            }
        }
        return headers;
    }
}
